package org.ehe.erp.service.product.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ehe.business.supplier.domain.SupplierInfo;
import org.ehe.business.supplier.service.SupplierInfoService;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.erp.domain.product.ErpProductArrival;
import org.ehe.erp.domain.product.bo.ErpProductArrivalBo;
import org.ehe.erp.domain.purchase.ErpPurchaseOrder;
import org.ehe.erp.domain.product.vo.ErpProductArrivalVo;
import org.ehe.erp.mapper.product.ErpProductArrivalMapper;
import org.ehe.erp.service.product.BatchArrivalService;
import org.ehe.erp.service.product.ErpProductArrivalService;
import org.ehe.erp.service.purchase.IErpPurchaseOrderService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * ERP 订单到货信息
 * @author :zhangnn
 * @className :ErpProductArrivalServiceImpl
 * @description: TODO
 * @date 2025-08-19 09:16:49
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ErpProductArrivalServiceImpl extends ServiceImpl<ErpProductArrivalMapper, ErpProductArrival> implements ErpProductArrivalService {

    private final SupplierInfoService supplierInfoService;
    private final IErpPurchaseOrderService purchaseOrderService;
    //批次到货
    private final BatchArrivalService batchArrivalService;

    /**
     * 查询产品到货信息
     *
     * @param id 产品到货信息主键
     * @return 产品到货信息
     */
    @Override
    public ErpProductArrivalVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询产品到货信息列表
     *
     * @param bo        产品到货信息
     * @param pageQuery 分页查询条件
     * @return 产品到货信息集合
     */
    @Override
    public TableDataInfo<ErpProductArrivalVo> queryPageList(ErpProductArrivalBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ErpProductArrival> lqw = buildQueryWrapper(bo);
        Page<ErpProductArrivalVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(t->{
            SupplierInfo supplierInfo = supplierInfoService.getById(t.getSupplierId());
            if(Objects.nonNull(supplierInfo)){
                t.setSupplierName(supplierInfo.getSupplierName());
            }
            //付款单名称
            ErpPurchaseOrder order = purchaseOrderService.queryByOrderNo(t.getNo());
            if(Objects.nonNull(order)){
                t.setPurchaseOrderName(order.getName());
            }
        });
        return TableDataInfo.build(result);
    }

    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<ErpProductArrival> buildQueryWrapper(ErpProductArrivalBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ErpProductArrival> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getNo()), ErpProductArrival::getNo, bo.getNo());
        lqw.like(StringUtils.isNotBlank(bo.getBatchName()), ErpProductArrival::getBatchName, bo.getBatchName());
        lqw.eq(bo.getBatchId() != null, ErpProductArrival::getBatchId, bo.getBatchId());
        lqw.eq(bo.getStatus() != null, ErpProductArrival::getStatus, bo.getStatus());
        lqw.eq(bo.getDeliveryTime() != null, ErpProductArrival::getDeliveryTime, bo.getDeliveryTime());
        lqw.eq(bo.getSupplierId() != null, ErpProductArrival::getSupplierId, bo.getSupplierId());
        lqw.eq(bo.getCreateDept() != null, ErpProductArrival::getCreateDept, bo.getCreateDept());
        if (null != params) {
            lqw.between(params.get("beginDeliveryTime") != null && params.get("endDeliveryTime") != null,
                ErpProductArrival::getDeliveryTime, params.get("beginDeliveryTime"), params.get("endDeliveryTime"));
        }

        lqw.orderByDesc(ErpProductArrival::getCreateTime);
        return lqw;
    }

    /**
     * 新增产品到货信息
     *
     * @param bos 产品到货信息
     * @return 结果
     */
    @Override
    public Boolean insertByBo(List<ErpProductArrivalBo> bos) {
        boolean flag = false;
        for (ErpProductArrivalBo bo : bos) {
            ErpProductArrival add = BeanUtil.toBean(bo, ErpProductArrival.class);
            if(null == add.getSupplierId()){
                ErpPurchaseOrder order = purchaseOrderService.queryByOrderNo(bo.getNo());
                add.setSupplierId(order.getSupplierId());
            }
            flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setId(add.getId());
            }
        }

        return flag;
    }

    /**
     * 修改产品到货信息
     *
     * @param bos 产品到货信息
     * @return 结果
     */
    @Override
    public Boolean updateByBo(List<ErpProductArrivalBo> bos) {
        for (ErpProductArrivalBo bo : bos) {
            System.out.println(bo.getRemark());

            // 获取更新前的状态
            ErpProductArrival oldArrival = baseMapper.selectById(bo.getId());
            Integer oldStatus = oldArrival != null ? oldArrival.getStatus() : null;

            ErpProductArrival update = MapstructUtils.convert(bo, ErpProductArrival.class);
            baseMapper.updateById(update);

            // 如果状态从非到货变为到货，触发BOM到货检查
            if (oldStatus != null && !oldStatus.equals(1) && bo.getStatus() != null && bo.getStatus().equals(1)) {
                log.info("产品到货状态更新为已到货，触发BOM到货检查，到货记录ID：{}", bo.getId());
                try {
                    batchArrivalService.onProductArrivalStatusChanged(bo.getId(), bo.getStatus());
                } catch (Exception e) {
                    log.error("处理到货状态变更事件失败，到货记录ID：{}", bo.getId(), e);
                    // 不抛出异常，避免影响主业务流程
                }
            }
        }
        return true;
    }

    /**
     * 校验并批量删除产品到货信息
     *
     * @param ids     需要删除的产品到货信息主键集合
     * @param isValid 是否校验,true-删除前校验,false-不校验
     * @return 结果
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 检查付款单号是否存在
     *
     * @param no 付款单号
     * @return true-存在, false-不存在
     */
    @Override
    public boolean checkNoExists(String no) {
        return baseMapper.exists(new LambdaQueryWrapper<ErpProductArrival>()
            .eq(ErpProductArrival::getNo, no));
    }

    /**
     * 检查付款单号是否存在（排除自身）
     *
     * @param no 付款单号
     * @param id 排除的ID
     * @return true-存在, false-不存在
     */
    @Override
    public boolean checkNoExistsExcludeSelf(String no, Long id) {
        return baseMapper.exists(new LambdaQueryWrapper<ErpProductArrival>()
            .eq(ErpProductArrival::getNo, no)
            .ne(ErpProductArrival::getId, id));
    }

    /**
     * 根据批次ID查询到货信息列表
     *
     * @param batchId 批次ID
     * @return 到货信息列表
     */
    @Override
    public List<ErpProductArrivalVo> queryByBatchId(Long batchId) {
        return baseMapper.selectVoList(new LambdaQueryWrapper<ErpProductArrival>()
            .eq(ErpProductArrival::getBatchId, batchId)
            .orderByDesc(ErpProductArrival::getDeliveryTime));
    }

    /**
     * 根据供应商ID查询到货信息列表
     *
     * @param supplierId 供应商ID
     * @return 到货信息列表
     */
    @Override
    public List<ErpProductArrivalVo> queryBySupplierId(Long supplierId) {
        return baseMapper.selectVoList(new LambdaQueryWrapper<ErpProductArrival>()
            .eq(ErpProductArrival::getSupplierId, supplierId)
            .orderByDesc(ErpProductArrival::getDeliveryTime));
    }

    /**
     * 批量更新状态
     *
     * @param ids    主键集合
     * @param status 状态
     * @return 结果
     */
    @Override
    public Boolean updateStatusByIds(Collection<Long> ids, Integer status) {
        if (ObjectUtil.isEmpty(ids)) {
            return false;
        }
        ids.forEach(id->{
            ErpProductArrival arrival = this.baseMapper.selectById(id);
            arrival.setStatus(status);
            this.baseMapper.updateById(arrival);
        });
       return true;
    }
}
